#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include "GLFWApplication.hpp"

GLFWApplication* GLFWApplication::sInstance = nullptr;

// glfw: whenever the window_ size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	if (GLFWApplication::sInstance)
	{
		GLFWApplication::sInstance->onSizeChange(width, height);
	}
}

int GLFWApplication::Initialize()
{
	sInstance = this;
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifndef _WIN32    
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
	winWidth_ = config_.width;
	winHeight_ = config_.height;

	window_ = glfwCreateWindow(winWidth_, winHeight_, config_.appName, NULL, NULL);
	if (window_ == NULL)
	{
		std::cout << "Failed to create GLFW window_" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window_);
	glfwSetFramebufferSizeCallback(window_, framebuffer_size_callback);

	// glad: load all OpenGL function pointers
	// ---------------------------------------
	if (!gladLoadGL())
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}
	return 0;
}

void GLFWApplication::Finalize()
{
	glfwDestroyWindow(window_);
	glfwTerminate();
}

void GLFWApplication::Tick()
{
	if (!glfwWindowShouldClose(window_))
	{
		// input
		// -----
		processInput(window_);

		// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
		// -------------------------------------------------------------------------------
		glfwSwapBuffers(window_);
		glfwPollEvents();
	}
	else
	{
		quit_ = true;
	}
}

void GLFWApplication::processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}


